using JavaVirtualMachine;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;

public class NativeMethodAttribute : Attribute
{
    public string Descriptor;
    public NativeMethodAttribute(string descriptor)
    {
        Descriptor = descriptor;
    }
}

public interface INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack);
}

#region Canvas
[NativeMethodAttribute("javax/microedition/lcdui/Canvas-Repaint-(IIII)V")]
public class Repaint : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int key = args[0];
        int x = args[1];
        int y = args[2];
        int w = args[3];
        int h = args[4];
        GameGraphics.Ins.Repaint(key,x,y,w,h);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

#endregion

#region RecordStore
[NativeMethodAttribute("javax/microedition/rms/RecordStore-GetNumRecords-()I")]
public class GetNumRecords : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(thisObj.GetField("name", "Ljava/lang/String;"));

        string path = StartScript.Ins.AppDirectoryPath + "/" + name;
        var files = Directory.GetFiles(path);
        JavaHelper.ReturnValue(MethodFrameStack, GlobalStack, files.Length);
    }
}

[NativeMethodAttribute("javax/microedition/rms/RecordStore-ListRecordStores-()[Ljava/lang/String;")]
public class ListRecordStores : INativeMethod
{
    public static HeapArray ListRecord;
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string path = StartScript.Ins.AppDirectoryPath;
        var directories = Directory.GetDirectories(path);
        if(directories.Length>0)
        {
            if (ListRecord == null)
                ListRecord =Heap.GetArray( Heap.CreateArray(4,directories.Length, ClassObjectManager.GetClassObjectAddr("Ljava/lang/String;")));
            JavaHelper.ReturnValue(MethodFrameStack, GlobalStack, ListRecord.Address);
        }
        else
            JavaHelper.ReturnValue(MethodFrameStack, GlobalStack, 0);
    }
}

[NativeMethodAttribute("javax/microedition/rms/RecordStore-GetSizeAvailable-()I")]
public class GetSizeAvailable : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        //string name = JavaHelper.ReadJavaString(thisObj.GetField("name", "Ljava/lang/String;"));

        //string path = StartScript.Ins.AppDirectoryPath + "/" + name;
        
        JavaHelper.ReturnValue(MethodFrameStack, GlobalStack, 16000000);
    }
}

[NativeMethodAttribute("javax/microedition/rms/RecordStore-GetNextRecordID-()I")]
public class GetNextRecordID : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(thisObj.GetField("name", "Ljava/lang/String;"));

        string path = StartScript.Ins.AppDirectoryPath + "/" + name;
        var files = Directory.GetFiles(path);
        JavaHelper.ReturnValue(MethodFrameStack, GlobalStack, files.Length+1);
    }
}

[NativeMethodAttribute("javax/microedition/rms/RecordStore-DeleteRecordStore-(Ljava/lang/String;)V")]
public class DeleteRecordStore : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(args[0]);

        string path = StartScript.Ins.AppDirectoryPath + "/" + name;
        if(Directory.Exists(path))
        {
            string[] files= Directory.GetFiles(path);
            for (int i = 0; i < files.Length; i++)
            {
                File.Delete(files[i]);
            }
           Directory.Delete(path);
        }
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}
#endregion
#region CreateImage

[NativeMethodAttribute("javax/microedition/lcdui/Image-CreateImageEvent-(Ljava/lang/String;)V")]
public class CreateImageEvent : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(args[1]);
        Console.WriteLine("CreateImageEvent: " + name);
        int key = args[0];
        Image_ image = FileStreams.GetImage(key);
        if (image == null)
        {
            image = new Image_(name);
            image.name = "Image";
            FileStreams.AddImage(key, image);
        }

        thisObj.SetField("Width", "I", image.width);
        thisObj.SetField("Height", "I", image.height);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Image-CreateImageEvent-([BII)V")]
public class CreateImageEvent1 : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(thisObj.GetField("ImageName", "Ljava/lang/String;"));
        HeapArray array = Heap.GetArray(args[1]);
        int key = args[0];
        int index = args[2];
        int lenght = args[3];
        Console.WriteLine("CreateImageEvent1: " + name +"   index:"+index+ "   lenght:" + lenght);
        Image_ image =new Image_(array.GetDataSpan(),index,lenght);
        image.name = "Image1";
        FileStreams.AddImage(key, image);

        thisObj.SetField("Width", "I", image.width);
        thisObj.SetField("Height", "I", image.height);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Image-CreateImageEvent-([B)V")]
public class CreateImageEvent3 : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(thisObj.GetField("ImageName", "Ljava/lang/String;"));
        HeapArray array = Heap.GetArray(args[1]);
        int key = args[0];
        Console.WriteLine("CreateImageEvent3: " + name);
        Image_ image = new Image_(array.GetDataSpan().ToArray());
        image.name = "Image3";
        FileStreams.AddImage(key, image);

        thisObj.SetField("Width", "I", image.width);
        thisObj.SetField("Height", "I", image.height);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Image-CreateImageEvent-(Ljavax/microedition/lcdui/Image;IIIII)V")]
public class CreateImageEvent0 : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(thisObj.GetField("ImageName", "Ljava/lang/String;"));

        int key0 = args[0];
        int key = args[1];
        int x = args[2];
        int y = args[3];
        int w = args[4];
        int h = args[5];
        int transform = args[6];
        Console.WriteLine("CreateImageEvent0: " + name + "   x:" + x + "   y:" + y + "   w:" + w + "   h:" + h);
        Image_ image = FileStreams.GetImage(key);
        if (image != null)
        {
            image = new Image_(image,x,y,w,h, transform);
            image.name = "Image0";
            FileStreams.AddImage(key0, image);
        }
        else
        {
            throw new Exception("image is null");
        }

        thisObj.SetField("Width", "I", image.width);
        thisObj.SetField("Height", "I", image.height);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Image-CreateImageEvent-([IIIZ)V")]
public class CreateRGBImageEvent : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(thisObj.GetField("ImageName", "Ljava/lang/String;"));
        HeapArray array = Heap.GetArray(args[1]);
        int key = args[0];
        int w = args[2];
        int h = args[3];
        int processAlpha = args[4];
        Console.WriteLine("CreateRGBImageEvent: " + name + "    w:" + w + "   h:" + h+ "  processAlpha:" + processAlpha);

        Image_ image = FileStreams.GetImage(key);
        if (image == null)
        {
            image = new Image_(array,w,h, processAlpha);
            FileStreams.AddImage(key, image);
        }

        thisObj.SetField("Width", "I", image.width);
        thisObj.SetField("Height", "I", image.height);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Image-GetRGB-([IIIIIII)V")]
public class GetRGB : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(thisObj.GetField("ImageName", "Ljava/lang/String;"));
        int key = args[0];
        HeapArray array = Heap.GetArray(args[1]);
        int offset = args[2];
        int scanlength = args[3];
        int x = args[4];
        int y = args[5];
        int w = args[6];
        int h = args[7];
        Console.WriteLine("GetRGB: " + name + "    w:" + w + "   h:" + h);

        Image_ image = FileStreams.GetImage(key);
        if (image == null)
        {
            throw new Exception("GetRGB error");
        }
        else
        {
            byte[] data = image.GetARGBData(x, y, w, h, 0);
            data.CopyTo(array.GetDataSpan());
            
        }

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Image-CreateImageEvent-(II)V")]
public class CreateImageEvent2 : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string name = JavaHelper.ReadJavaString(thisObj.GetField("ImageName", "Ljava/lang/String;"));

        int key = args[0];
        int w = args[1];
        int h = args[2];
        Console.WriteLine("CreateImageEvent2: " + name + "    w:" + w + "   h:" + h);

        Image_ image = FileStreams.GetImage(key);
        if (image == null)
        {
            image = new Image_(w, h);
            FileStreams.AddImage(key, image);
        }

        thisObj.SetField("Width", "I", image.width);
        thisObj.SetField("Height", "I", image.height);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}
#endregion

#region Graphics
[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawImage-(Ljavax/microedition/lcdui/Image;III)V")]
public class DrawImage0 : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        HeapObject cFileObj = Heap.GetObject(args[1]);
        string name = JavaHelper.ReadJavaString(cFileObj.GetField("ImageName", "Ljava/lang/String;"));
        //int key = thisObj.GetField("Displayable", "Ljavax/microedition/lcdui/Displayable;");
        int key = 0;
        int x = args[2];
        int y = args[3];
        int value = args[4];
        GameGraphics.Ins.AddImage(key, args[1], name, x, y, value);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-SetColor-(III)V")]
public class SetColor : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int key = args[0];
        int r = args[1];
        int g = args[2];
        int b = args[3];
        //Console.WriteLine("SetColor: "  + "    r:" + r + "   g:" + g + "   b:" + b);
        GameGraphics.Ins.SetColor(r, g, b);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-SetClip-(IIII)V")]
public class SetClip : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int key = args[0];
        int x = args[1];
        int y = args[2];
        int w = args[3];
        int h = args[3];
        //Console.WriteLine("SetClip: " + "    x:" + x + "   g:" + y + "   w:" + w + "   h:" + h);
        GameGraphics.Ins.SetClip(x, y, w, h);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawRegion-(Ljavax/microedition/lcdui/Image;IIIIIIII)V")]
public class DrawRegion : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int key = args[1];
        Image_ image = FileStreams.GetImage(key);
        int x = args[2];
        int y = args[3];
        int w = args[4];
        int h = args[5];
        int transform = args[6];
        int x0 = args[7];
        int y0 = args[8];
        int anchor = args[9];
        Image_ image1= new Image_(image, x, y, w, h, transform);
        image1.anchor = anchor;
        //image1.drawRegion(image.bmp, x, y, w, h, transform, x0, y0, anchor);
        GameGraphics.Ins.DrawImageData(image1, x0, y0);
        //Console.WriteLine("DrawRegion: " + "    x:" + x + "   y:" + y + "   w:" + w + "   h:" + h + "   transform:" + transform + "   x0:" + x0 + "   y0:" + y0);

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawRect-(IIII)V")]
public class DrawRect : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int x = args[1];
        int y = args[3];
        int w = args[3];
        int h = args[4];
        Image_ image = new Image_(w, h,true,true);
        GameGraphics.Ins.DrawImageData(image, x, y);
        //Console.WriteLine("DrawRect: " + "    x:" + x + "   y:" + y + "   w:" + w + "   h:" + h );

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawArc-(IIIIII)V")]
public class DrawArc : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int x = args[1];
        int y = args[3];
        int w = args[3];
        int h = args[4];
        int startAngle = args[5];
        int arcAngle = args[6];
        //Image_ image = new Image_(w, h, true, true);
        //GameGraphics.Ins.DrawImageData(image, x, y);
        //Console.WriteLine("DrawArc: " + "    x:" + x + "   y:" + y + "   w:" + w + "   h:" + h );

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawLine-(IIII)V")]
public class DrawLine : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int x1 = args[1];
        int y1 = args[3];
        int x2 = args[3];
        int y2 = args[4];
        GameGraphics.Ins.DrawImageData(new Image_(x1,y1,x2,y2), x1<x2?x1:x2,y1<y2?y2:y1);
        //Console.WriteLine("DrawRect: " + "    x:" + x + "   y:" + y + "   w:" + w + "   h:" + h );

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawChar-(CIII)V")]
public class DrawChar : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int character = args[1];
        int x = args[2];
        int y = args[3];
        int anchor = args[4];

        //Console.WriteLine("DrawChar: " + "    x:" + x + "   y:" + y + "   w:" + w + "   h:" + h );
        GameGraphics.Ins.DrawText(character,x,y, anchor);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawChars-([CIIIII)V")]
public class DrawChars : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        HeapArray array = Heap.GetArray(args[1]);

        int offset = args[2];
        int length = args[3];
        int x = args[4];
        int y = args[5];
        int anchor = args[6];
        GameGraphics.Ins.DrawText(array.GetDataSpan().ToArray().Skip(offset).Take(length* array.ItemSize).ToArray(), x, y, 0);

        //Console.WriteLine("DrawChar: " + "    x:" + x + "   y:" + y + "   w:" + w + "   h:" + h );

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawRGB-([IIIIIIIZ)V")]
public class DrawRGB : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        int key = args[1];
        HeapArray array = Heap.GetArray(args[1]);
        int offset = args[2];
        int scanlength = args[3];
        int x = args[4];
        int y = args[5];
        int w = args[6];
        int h = args[7];
        int processAlpha = args[8];
        GameGraphics.Ins.DrawImageData(new Image_(array, offset, scanlength, w, h,processAlpha), x, y);
        //Console.WriteLine("DrawRegion: " + "    x:" + x + "   y:" + y + "   w:" + w + "   h:" + h + "   x0:" + x0 + "   y0:" + y0);

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-DrawString-(Ljava/lang/String;III)V")]
public class DrawString : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        string str = JavaHelper.ReadJavaString(args[1], true);
        int x = args[2];
        int y = args[3];
        int anchor = args[4];
        GameGraphics.Ins.AddText(args[0], str, x, y, anchor);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
        //Console.WriteLine("DrawString: " + "    x:" + x + "   y:" + y + "   size:" + size);

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-SetColor-(I)V")]
public class SetColor1 : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        GameGraphics.ColorValue = args[1];
        int r = (GameGraphics.ColorValue << 8) & 255;
        int g = (GameGraphics.ColorValue << 4) & 255;
        int b = (GameGraphics.ColorValue) & 255;
        //Console.WriteLine("SetColor: "  + "    r:" + r + "   g:" + g + "   b:" + b);

        GameGraphics.Ins.SetColor(r, g, b);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Graphics-FillRect-(IIII)V")]
public class FillRect : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        //GameGraphics.Ins.FillRect(args[1], args[2], args[3], args[4]);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}
#endregion

#region Displayable
[NativeMethodAttribute("javax/microedition/lcdui/Displayable-RemoveCommand-(Ljavax/microedition/lcdui/Command;)V")]
public class RemoveCommand : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        HeapObject cObj = Heap.GetObject(args[1]);

        string name = JavaHelper.ReadJavaString(cObj.GetField("label", "Ljava/lang/String;"), true);
        int type = cObj.GetField("type", "I");
        int priority = cObj.GetField("priority", "I");
        GameGraphics.Ins.RemoveCommand(args[0], args[1], name, type, priority);

        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}

[NativeMethodAttribute("javax/microedition/lcdui/Displayable-ShowTitle-()V")]
public class ShowTitle : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        HeapObject cFileObj = Heap.GetObject(args[0]);

        string Title = JavaHelper.ReadJavaString(cFileObj.GetField("Title", "Ljava/lang/String;"), true);

        GameGraphics.Ins.ShowTitle(args[0], Title);
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}
#endregion

#region Sprite
[NativeMethodAttribute("javax/microedition/lcdui/game/Sprite-SpriteInit-()V")]
public class SpriteInit : INativeMethod
{
    public void Execute(HeapObject thisObj, int[] args, Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        Console.WriteLine("SpriteInit()");
        JavaHelper.ReturnVoid(MethodFrameStack, GlobalStack);
    }
}
#endregion

public static class NativeMethodFactory
{
    private static Dictionary<string, Type> sDictionary = null;
    private static Dictionary<Type, INativeMethod> cDictionary = null;

    static NativeMethodFactory()
    {
        Initialize();
    }
    private static void Initialize()
    {
        sDictionary = new Dictionary<string, Type>();
        cDictionary = new Dictionary<Type, INativeMethod>();
        Type[] types = typeof(NativeMethodFactory).Assembly.GetTypes();
        foreach (var cls in types)
        {
            if (!cls.IsClass) continue;
            if (!cls.GetInterfaces().Contains(typeof(INativeMethod))) continue;
            if (cls.GetConstructor(new Type[0]) == null) continue;

            var attr = (NativeMethodAttribute)cls.GetCustomAttributes(typeof(NativeMethodAttribute), false).FirstOrDefault();
            if (attr == null) continue;

            sDictionary.Add(attr.Descriptor,  cls);
        }
    }

    public static INativeMethod ExecuteNativeMethod(string className,string thisFuncName,string thisDescriptor, HeapObject thisObj, int[] args,
        Stack<MethodFrame> MethodFrameStack, Memory<int> GlobalStack)
    {
        if (sDictionary == null)
            Initialize();
        Type info;
        string key = className + "-" + thisFuncName + "-" + thisDescriptor;
        if (!sDictionary.TryGetValue(key, out info))
        {
            return null;
        }
        INativeMethod tag =null;
        //if (!cDictionary.TryGetValue(info, out tag))
        {
            tag = (INativeMethod)Activator.CreateInstance(info);
            //cDictionary.Add(info, tag);
        }
        tag.Execute(thisObj,args, MethodFrameStack, GlobalStack);
        return tag;
    }
}